/**
 * Created by 懒猫 swgger3.0接口 on 2021/12/20.
 * 修改：2022-3-11 修改requestBody中使用 [FromForm]
 */
; layui.define(function (exports) {
    "use strict";

    var $ = layui.jquery;
    var g_ = {};
    var g_apidoc;
    var g_components;

    g_.resolve = function (_apidoc) {

        _apidoc.schemes || (_apidoc.schemes = ["http"]);
        g_apidoc = _apidoc;
        g_components = _apidoc['components'];
        //
        _parse();
    }

    /**
     * 解析API文档
     */
    function _parse() {

        // 遍历处理TAGS，初始化依赖路径列表
        $.map(g_apidoc['tags'], function (item) {
            item['paths'] = [];
        });
        // 遍历处理路径，处理路径方法
        $.each(g_apidoc['paths'], function (path, pathmeta) {

            $.each(pathmeta, function (httpmethod, methodmeta) {

                // 将该路径方法添加到对应的TAG中
                add2tags(path, httpmethod, methodmeta, g_apidoc['tags']);
                //console.info(111, methodmeta);
                // 处理路径方法
                add2method(methodmeta);

            });
        });

        /**
         * 解析每个路径的每一个HttpMethod对应的方法
         * @param path          路径
         * @param httpmethod    HttpMethod（GET,POST,PUT,DELETE）
         * @param methodmeta    每个Method对应的方法描述
         * @param tags          总的Tags数据
         */
        function add2tags(path, httpmethod, methodmeta, tags) {
            // 遍历模块
            $.each(methodmeta['tags'], function (i, item) {
                $.each(tags, function (i, tag) {
                    if (tag["name"] == item) {
                        tag['paths'].push({
                            name: methodmeta['summary'],
                            description: methodmeta['description'],
                            path: path,
                            httpmethod: httpmethod
                        });
                    }
                })
            })
        }

        /**
         * 添加自定义参数或返回值类型
         * @param methodmeta
         */
        function add2method(methodmeta) {
            console.info("param=", methodmeta);
            var schema = { request: [], responses: [] };
            methodmeta['models'] = schema;
            // 处理参数的Model
            methodmeta.hasOwnProperty('parameters') && $.each(methodmeta['parameters'], function (i, param) {
                var obj = {
                    name: param.name,//名称
                    type: dataType(param.schema.type, param.schema.format),//类型
                    description: param.description,//说明
                    default: param.schema.default,//默认值
                    required: param.required,//是否必填
                    sort: 0,//排序
                    submodel: false//是否有子集
                }
                methodmeta['models']["request"].push(obj);
            });

            //处理requestBody 接收参数只能有一个[FromBody]           
            if (methodmeta.hasOwnProperty("requestBody")) {

                
                var schema;
                if (!!methodmeta.requestBody.content["application/json"]) {
                    schema = methodmeta.requestBody.content["application/json"].schema;
                }
                else if (!!methodmeta.requestBody.content["multipart/form-data"]) {
                    schema = methodmeta.requestBody.content["multipart/form-data"].schema;
                }

                var obj = {
                    name: "参数名",//名称
                    type: type,//类型
                    description: methodmeta.requestBody.description,//说明
                    default: "",//默认值
                    required: "",//是否必填
                    sort: 1,//排序
                    submodel: false//是否有子集
                }
                var type;
                if (schema.hasOwnProperty("$ref")) {
                    obj.type = cutDefinition(schema["$ref"]);
                    obj.submodel = true;
                    SetPmeta(methodmeta['models']["request"], obj.type, 2);
                }
                else if (schema.type == "array") {
                    var item;
                    if (schema.items.hasOwnProperty("$ref")) {
                        //schema:{
                        //    "type": "array",
                        //    "items": {
                        //          "$ref": "#/components/schemas/SysRole"
                        //    }
                        //}
                        obj.submodel = true;
                        item = cutDefinition(schema.items["$ref"]);
                        SetPmeta(methodmeta['models']["request"], item, 2);
                    }
                    else {
                        //schema: {
                        //    type: array,
                        //        items: {
                        //        type: string
                        //    }
                        //}
                        item = schema.items.type;
                    }
                    obj.type = "Array[" + item + "]";
                }
                else if (schema.type == "object") {
                    console.info("3333333han");
                    obj.type = "object";
                    SetrequestBody(methodmeta['models']["request"], schema.properties, 2);
                }
                else {
                    obj.type = schema.type;
                }
                //console.info("type=" + type);


                methodmeta['models']["request"].push(obj);
            }

            // 处理响应的Model
            $.each(methodmeta['responses'], function (status, response) {
                ///存在content
                if (response.hasOwnProperty("content")) {
                    var schema = response.content["application/json"].schema;
                    var obj = {
                        name: "参数名",//名称
                        type: type,//类型
                        description: schema.description,//说明
                        default: "",//默认值
                        required: "",//是否必填
                        sort: 0,//排序
                        submodel: false//是否有子集
                    }

                    if (schema.hasOwnProperty("$ref")) {
                        obj.type = cutDefinition(schema["$ref"]);
                        obj.submodel = true;
                        SetPmeta(methodmeta['models']["responses"], obj.type, 1);
                    }
                    else if (schema.type == "array") {
                        var item;
                        if (schema.items.hasOwnProperty("$ref")) {
                            //schema:{
                            //    "type": "array",
                            //    "items": {
                            //          "$ref": "#/components/schemas/SysRole"
                            //    }
                            //}
                            obj.submodel = true;
                            item = cutDefinition(schema.items["$ref"]);
                            SetPmeta(methodmeta['models']["responses"], item, 1);
                        }
                        else {
                            //schema: {
                            //    type: array,
                            //        items: {
                            //        type: string
                            //    }
                            //}
                            item = schema.items.type;
                        }
                        obj.type = "Array[" + item + "]";
                    }
                    else {
                        obj.type = schema.type;
                    }

                    methodmeta['models']["responses"].push(obj);
                }
                {
                    //"responses": {
                    //    "200": {
                    //        "description": "Success"
                    //    }
                    //}
                    //"responses": {
                    //    "200": {
                    //        "description": "Success",
                    //            "content": {
                    //            "application/json": {
                    //                "schema": {
                    //                    "type": "array",
                    //                        "items": {
                    //                        "type": "string"
                    //                    }
                    //                }
                    //            }
                    //        }
                    //    }
                    //}
                    //"responses": {
                    //    "200": {
                    //        "description": "Success",
                    //            "content": {
                    //            "application/json": {
                    //                "schema": {
                    //                    "type": "array",
                    //                        "items": {
                    //                        "$ref": "#/components/schemas/SysRole"
                    //                    }
                    //                }
                    //            },
                    //        }
                    //    }
                    //}
                    //"responses": {
                    //    "200": {
                    //        "description": "Success",
                    //            "content": {
                    //            "application/json": {
                    //                "schema": {
                    //                    "type": "string"
                    //                }
                    //            },
                    //        }
                    //    }
                    //}

                    //"responses": {
                    //    "200": {
                    //        "description": "Success",
                    //            "content": {
                    //            "application/json": {
                    //                "schema": {
                    //                    "$ref": "#/components/schemas/ApiModel"
                    //                }
                    //            },
                    //        }
                    //    }
                    //}
                }



            });
            methodmeta['models']["request"].sort((a, b) => a.sort - b.sort)
            methodmeta['models']["responses"].sort((a, b) => a.sort - b.sort)


        }



        /**
         * 截取Model定义，方便显示
         *
         * @param definition
         * @returns {*}
         */
        function cutDefinition(definition) {
            if (definition) {
                return definition.substr(definition.lastIndexOf('/') + 1);
            }
            return "";
        }

        /**
         * 包装Model为链接
         *
         * @param type
         * @returns {string}
         */
        function wrapShowType(type) {
            return "<a href=\"javascript:gotoModel('" + type + "');\">" + type + "</a>";
        }

        function SetrequestBody(pModels, path, sort) {
            $.each(path, function (pname, prop) {
                var obj = {
                    name: pname,//名称
                    type: dataType(prop.type, prop.format),//类型
                    description: prop.description,//说明
                    default: "",//默认值
                    sort: sort,//排序
                    required: prop.nullable,//是否必填
                    submodel: false//是否有子集
                }
                pModels.push(obj);
            });

        };

        function SetPmeta(pModels, type, sort) {
            console.info("1111", pModels, type, sort);
            $.each(g_components.schemas[type].properties, function (pname, prop) {
                var obj = {
                    name: pname,//名称
                    type: dataType(prop.type, prop.format),//类型
                    description: prop.description,//说明
                    default: "",//默认值
                    sort: sort,//排序
                    required: prop.nullable,//是否必填
                    submodel: false//是否有子集
                }
                if (prop.hasOwnProperty("$ref")) {
                    console.info("3333");
                    obj.sort = obj.sort + 1;
                    obj.type = cutDefinition(prop["$ref"]);
                    obj.submodel = true
                    SetPmeta(pModels, obj.type, obj.sort + 1);
                }
                else if (prop.hasOwnProperty("items")) {
                    if (prop.items.hasOwnProperty("$ref")) {
                        console.info("4444");
                        obj.sort = obj.sort + 1;
                        obj.submodel = true
                        var ref = cutDefinition(prop.items["$ref"]);
                        if (prop.type == "array") obj.type = "Array[" + ref + "]";
                        SetPmeta(pModels, ref, obj.sort + 1);
                    }
                }

                console.info(obj.sort);

                pModels.push(obj);
            });
        }

        /**
         *
         * @param type
         * @param format
         * @returns {*}
         */
        function dataType(type, format) {
            if (format && format != "") {
                switch (format) {
                    case "int32":
                        return "int";
                    case "int64":
                        return "long";
                    case "float":
                    case "double":
                    case "byte":
                    case "binary":
                    case "date":
                        return format;
                    case "date-time":
                        return "datetime";
                    case "password":
                        return "string(" + format + ")";
                    default:
                        return "string";
                }
            } else {
                return type;
            }
        }
    }

    /**
     * 创建JSON对象的数据模板，用于生成发送请求参数
     */
    g_.jsonmock = (function () {

        var _ = {
            mock: function (content) {
                var schema;
                if (!!content["application/json"]) {
                    schema = content["application/json"].schema;
                }
                else if (!!content["multipart/form-data"]) {
                    schema = content["multipart/form-data"].schema;
                }
                console.info(schema);
                var type, proType = "object";
                var model = {};
                if (schema.hasOwnProperty("$ref")) {
                    type = substr(schema["$ref"]);
                    SetGenMock(model, proType, type);
                }
                else if (schema.type == "array") {
                    proType = "array";
                    model = [];
                    if (schema.hasOwnProperty("items")) {
                        if (schema.items.hasOwnProperty("$ref")) {
                            type = substr(schema.items["$ref"]);
                        }
                    }
                    else {
                        type = schema.items.type;
                    }
                    SetGenMock(model, proType, type);
                }
                else if (schema.type == "object") {
                    console.info("00000000");
                    SetBodyMock(model, schema.properties);
                }
                else {
                    model["参数名"] = schema.type;
                }

                console.info(model);
                return JSON.stringify(model, null, '\t');
            }
        };

        function SetBodyMock(pModels, path) {
            $.each(path, function (pname, prop) {
                pModels[pname] = prop.type;
            });
        }

        function SetGenMock(pModels, proType, type) {
            if (proType == "array") {
                var obj = {}
            }
            $.each(g_components.schemas[type].properties, function (pname, prop) {

                if (prop.hasOwnProperty("$ref")) {
                    var types = substr(prop["$ref"]);
                    pModels[pname] = {};
                    SetGenMock(pModels[pname], "object", types);
                }
                else if (prop.hasOwnProperty("items")) {
                    if (prop.items.hasOwnProperty("$ref")) {
                        var ref = substr(prop.items["$ref"]);
                        if (prop.type == "array") pModels[pname] = [];
                        SetGenMock(pModels[pname], "array", ref);
                    }
                } else {
                    if (proType == "array") {
                        obj[pname] = prop.type;
                    }
                    else {
                        pModels[pname] = prop.type;
                    }
                }
            });
            if (proType == "array") {
                pModels.push(obj);
            }
        }

        function substr(definition) {
            if (definition) {
                return definition.substr(definition.lastIndexOf('/') + 1);
            }
            return "";
        }


        function genMockData(type) {
            switch (type) {
                case 'integer':
                case 'number':
                    return 0;
                case 'boolean':
                    return false;
                case 'string':
                default:
                    return ""
            }
        }

        return _;
    })();

    exports('nswagger', g_);
});